/**
 *  Created on  : 07/05/2012
 *  Author      : Ing. Javier Silva Pérez - [javier]
 *  Description :
 *  	RSA Key Pair abstraction, contains both public and private keys
 */
package cinvestav.cryptography.pki.android.key;

import java.security.KeyPair;
import java.security.interfaces.RSAPrivateCrtKey;

import org.spongycastle.crypto.AsymmetricCipherKeyPair;
import org.spongycastle.crypto.params.RSAKeyParameters;
import org.spongycastle.crypto.params.RSAPrivateCrtKeyParameters;

import cinvestav.cryptography.pki.android.exception.AndroidCryptoUtilsException;

/**
 * RSA Key Pair abstraction, contains both public and private keys
 * 
 * @author Ing. Javier Silva Pérez - [javier]
 * 
 */
public class RSAKeyPair {
	private RSAPrivateKey privateKey;
	private RSAPublicKey publicKey;

	/**
	 * Default constructor
	 */
	public RSAKeyPair() {
		super();
		this.privateKey = new RSAPrivateKey();
		this.publicKey = new RSAPublicKey();
	}

	/**
	 * Copy constructor
	 * 
	 * @param rsaKeyPair
	 *            Source key pair
	 */
	public RSAKeyPair(RSAKeyPair rsaKeyPair) {
		this.publicKey = new RSAPublicKey(rsaKeyPair.publicKey);
		this.privateKey = new RSAPrivateKey(rsaKeyPair.privateKey);
	}

	/**
	 * Constructor with parameters, init both public and private key
	 * 
	 * @param privateKey
	 * @param publicKey
	 */
	public RSAKeyPair(RSAPrivateKey privateKey, RSAPublicKey publicKey) {
		super();
		this.privateKey = privateKey;
		this.publicKey = publicKey;
	}

	public RSAPrivateKey getPrivateKey() {
		return privateKey;
	}

	public void setPrivateKey(RSAPrivateKey privateKey) {
		this.privateKey = privateKey;
	}

	public RSAPublicKey getPublicKey() {
		return publicKey;
	}

	public void setPublicKey(RSAPublicKey publicKey) {
		this.publicKey = publicKey;
	}
	
	

	@Override
	public String toString() {
		return "RSAKeyPair [privateKey=" + privateKey + ", publicKey="
				+ publicKey + "]";
	}
	
	/**
	 * ToString method using a specific encoder
	 * @param encoder see available encoders in {@link cinvestav.cryptography.pki.android.utils.AndroidCryptoUtils}
	 * @return	String Key Pair encoded
	 */
	public String toString(String encoder) {
		return "RSAKeyPair [privateKey=" + privateKey.toString(encoder) + ", publicKey="
				+ publicKey.toString(encoder) + "]";
	}

	/**
	 * Parse an AsymmetricCipherKeyPair (
	 * {@link org.spongycastle.crypto.AsymmetricCipherKeyPair}) object and store
	 * the result in the current object
	 * 
	 * @param keyPair
	 *            {@link org.spongycastle.crypto.AsymmetricCipherKeyPair
	 *            AsymmetricCipherKeyPair} object
	 */
	public void parseRSAKeyPair(AsymmetricCipherKeyPair keyPair) {
		this.privateKey.parseRSAPrivateKey((RSAPrivateCrtKeyParameters) keyPair
				.getPrivate());
		this.publicKey
				.parseRSAPublicKey((RSAKeyParameters) keyPair.getPublic());
	}

	/**
	 * Parse the current object to AsymmetricCipherKeyPair (
	 * {@link org.spongycastle.crypto.AsymmetricCipherKeyPair})
	 * 
	 * @return AsymmetricCipherKeyPair object containing to the current private
	 *         key
	 */
	public AsymmetricCipherKeyPair parseToAsymmetricCipherKeyPair() {
		AsymmetricCipherKeyPair keyPair = new AsymmetricCipherKeyPair(
				this.publicKey.parseToRSAKeyParameters(),
				this.privateKey.parseToRSAPrivateCrtKeyParameters());
		return keyPair;
	}

	/**
	 * Parse java JCE KeyPair ({@link java.security.KeyPair}) to RSA Key Pair
	 * 
	 * @param keyPair
	 * @throws AndroidCryptoUtilsException
	 */
	public void parseRSAKeyPair(KeyPair keyPair)
			throws AndroidCryptoUtilsException {
		if (keyPair.getPrivate() instanceof RSAPrivateCrtKey) {

			this.privateKey.parseRSAPrivateKey((RSAPrivateCrtKey) keyPair
					.getPrivate());
		} else {
			throw new AndroidCryptoUtilsException(
					"Parse error: "
							+ keyPair.getPrivate().getClass().toString()
							+ " not an instance of java.security.interfaces.RSAPrivateCrtKey");
		}

		if (keyPair.getPublic() instanceof java.security.interfaces.RSAPublicKey) {
			this.publicKey
					.parseRSAPublicKey((java.security.interfaces.RSAPublicKey) keyPair
							.getPublic());
		} else {
			throw new AndroidCryptoUtilsException(
					"Parse error: "
							+ keyPair.getPublic().getClass().toString()
							+ " not an instance of java.security.interfaces.RSAPublicKey");
		}

	}

	/**
	 * Parse the current object to Java JCE Key Pair (
	 * {@link java.security.KeyPair})
	 * 
	 * @return JCE Key Pair object
	 * @throws AndroidCryptoUtilsException
	 */
	public KeyPair parseToKeyPair() throws AndroidCryptoUtilsException {

		return new KeyPair(publicKey.parseToJCERSAPublicKey(),
				privateKey.parseToJCERSAPrivateCrtKey());

	}
}
